package com.ruoyi.client.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.gson.Gson;
import com.ruoyi.client.domain.BOrderCancelReq;
import com.ruoyi.client.domain.HousekeepingPayment;
import com.ruoyi.client.domain.LaunchHousekeepingOrderPayPrepareVo;
import com.ruoyi.client.domain.Pocket;
import com.ruoyi.client.domain.request.CancelDeBangOrderRequest;
import com.ruoyi.client.domain.response.CancelDeBangOrderResponse;
import com.ruoyi.client.service.ShoppingService;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.recycle.constant.OrderInfoConstant;
import com.ruoyi.recycle.domain.*;
import com.ruoyi.recycle.dto.PayCallBackInfo;
import com.ruoyi.recycle.dto.PaymentDTO;
import com.ruoyi.recycle.dto.PocketReq;
import com.ruoyi.recycle.dto.ResourceInfo;
import com.ruoyi.recycle.dto.deppon.response.ResultBeanResponse;
import com.ruoyi.recycle.mapper.*;
import com.ruoyi.recycle.properties.Wxproperties;
import com.ruoyi.recycle.service.IHousekeepingOrderService;
import com.ruoyi.recycle.service.IRecycleOrderService;
import com.ruoyi.recycle.service.RecycleRequestLogService;
import com.ruoyi.recycle.service.impl.WechatPaymentService;
import com.ruoyi.recycle.utils.OrderNoGenerateUtil;
import com.ruoyi.recycle.utils.debang.FastJsonUtil;
import com.ruoyi.recycle.utils.debang.HttpUtils;
import com.ruoyi.recycle.utils.debang.ResultDO;
import com.ruoyi.recycle.utils.kuaidi.SignUtils;
import com.ruoyi.recycle.utils.kuaidi.core.IBaseClient;
import com.ruoyi.recycle.utils.kuaidi.dto.ApiInfoConstant;
import com.ruoyi.recycle.utils.kuaidi.dto.BOrderOfficial;
import com.ruoyi.recycle.utils.kuaidi.dto.HttpResult;
import com.ruoyi.recycle.utils.kuaidi.dto.PrintReq;
import com.ruoyi.system.api.util.AesUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
@Slf4j
@RequiredArgsConstructor
public class ShoppingServiceImpl implements ShoppingService {

    private final static String POCKET_PREFIX = "POCKET";
    //假数据开始计算时间
    private final static String FAKE_DATA_DATE = "2023-07-12";
    //每日制造多少假数据
    private final static int STEP = 100;
    //uat
    //private final static String DEPPON_URL = "http://dpsanbox.deppon.com/sandbox-web/standard-order/cancelOrder.action";
    //prod
    private final static String DEPPON_URL = "http://gwapi.deppon.com/dop-interface-async/standard-order/cancelOrder.action";
    private final static String COMPANY_CODE = "EWBGDHAHBK";
    private final static String APP_KEY = "5ded13ec69eba019447e43e23470bdb0";

    @Resource
    private IntegralCommodityMapper integralCommodityMapper;
    @Resource
    private IntegralCommoditySizeMapper integralCommoditySizeMapper;
    @Resource(name = "redisTemplate")
    private RedisTemplate<String, List<Pocket>> pocketCache;
    @Resource
    private IRecycleOrderService recycleOrderService;
    @Resource
    private IHousekeepingOrderService housekeepingOrderService;
    @Resource
    private RecycleRequestLogService recycleRequestLogService;
    @Resource
    private LogisticsExpenditureStatisticsMapper logisticsExpenditureStatisticsMapper;
    @Resource
    private ClientUserManagementMapper clientUserManagementMapper;
    @Resource
    private IntegralConfigMapper integralConfigMapper;
    @Resource
    private OrderNoGenerateUtil orderNoGenerateUtil;
    @Autowired
    private WechatPaymentService wechatPaymentService;
    @Resource
    private BillRecordMapper billRecordMapper;
    @Resource
    private MerchantManagementMapper managementMapper;
    @Resource
    private ClientPrayerManagementMapper clientPrayerManagementMapper;

    private final Wxproperties wxproperties;


    @Override
    public AjaxResult pocket(PocketReq pocketReq) {
        IntegralCommodity integralCommodity = integralCommodityMapper.selectById(pocketReq.getCommodityId());
        IntegralCommoditySize integralCommoditySize = integralCommoditySizeMapper.selectById(pocketReq.getSizeId());
        if (ObjectUtils.isEmpty(integralCommodity)) {
            return AjaxResult.error("该商品已下架，请浏览其他商品");
        }

        if (ObjectUtils.isEmpty(integralCommoditySize)) {
            return AjaxResult.error("该规格商品已下架，请浏览其他商品");
        }

        Pocket pocket = new Pocket();
        pocket.setUserId(pocketReq.getUserId());
        pocket.setQuantity(pocketReq.getQuantity());
        pocket.setIntegralCommodity(integralCommodity);
        pocket.setIntegralCommoditySize(integralCommoditySize);
        pocket.setCreateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        putIntoPocket(pocket);
        return AjaxResult.success("添加商品成功");
    }

    @Override
    public AjaxResult deletePocketItem(PocketReq pocketReq) {
        final String key = POCKET_PREFIX + pocketReq.getUserId();
        List<Pocket> pocketList = pocketCache.opsForValue().get(key);

        if (CollUtil.isEmpty(pocketList)) {
            return AjaxResult.error("购物车为空");
        }


        List<Pocket> deletePocketItems = new ArrayList<>();

        JSONArray jsonArray = new JSONArray(pocketList);

        pocketList = new ArrayList<>();

        for (int i = 0; i < jsonArray.length(); i++) {
            Pocket pocket = new Pocket();
            JSONObject object = jsonArray.getJSONObject(i);
            String integralCommodityStr = object.get("integralCommodity").toString();
            IntegralCommodity integralCommodity = JSON.parseObject(integralCommodityStr, IntegralCommodity.class);

            String integralCommoditySizeStr = object.get("integralCommoditySize").toString();
            IntegralCommoditySize integralCommoditySize = JSON.parseObject(integralCommoditySizeStr, IntegralCommoditySize.class);

            pocket.setCreateDate(object.get("createDate").toString());
            pocket.setQuantity((int) object.get("quantity"));
            Integer userId = (int) object.get("userId");
            pocket.setUserId(userId.longValue());
            pocket.setIntegralCommodity(integralCommodity);
            pocket.setIntegralCommoditySize(integralCommoditySize);
            pocketList.add(pocket);
        }

        for (Pocket pocket : pocketList) {
            if (ObjectUtils.isNotEmpty(pocket.getIntegralCommodity()) &&
                    ObjectUtils.isNotEmpty(pocket.getIntegralCommoditySize()) &&
                    pocket.getIntegralCommodity().getId() == pocketReq.getCommodityId() &&
                    pocket.getIntegralCommoditySize().getId() == pocketReq.getSizeId()) {
                deletePocketItems.add(pocket);
            }
        }

        if (deletePocketItems.size() > 0) {
            Pocket product = deletePocketItems.get(0);
            if (product.getQuantity() > pocketReq.getQuantity()) {
                pocketList.remove(product);
                product.setQuantity(product.getQuantity() - pocketReq.getQuantity());
                pocketList.add(product);
            } else if (product.getQuantity() == pocketReq.getQuantity()) {
                pocketList.removeAll(deletePocketItems);
            } else {
                return AjaxResult.error("删除的数量不允许大于购物车中的数量");
            }
        }
        pocketCache.opsForValue().set(key, pocketList, 30 * 3, TimeUnit.DAYS);
        return AjaxResult.success("删除成功");
    }

    @Override
    public AjaxResult pocketList(Long userId) {
        final List<Pocket> pocketProducts = pocketCache.opsForValue().get(POCKET_PREFIX + userId);
/*        if (CollUtil.isNotEmpty(pocketProducts)) {
            pocketProducts.sort((sort1, sort2) -> DateUtil.compare(sort1.getCreateDate(), sort2.getCreateDate()));
        }*/
        return AjaxResult.success(pocketProducts);
    }


    @Override
    public AjaxResult cancelServiceOrder(String orderNo, Integer orderType) {
        //1是回收订单，2是家政服务订单
        if (orderType == 1) {
            RecycleOrder recycleOrder = recycleOrderService.getById(orderNo);
            if (ObjectUtils.isEmpty(recycleOrder)) {
                return AjaxResult.error("不存在订单号为：" + orderNo + "，的订单");
            }
            if ("1".equals(recycleOrder.getStatus()) || "2".equals(recycleOrder.getStatus())) {
                recycleOrder.setStatus("7");
                recycleOrderService.updateById(recycleOrder);
                //这里还得判断是否是快递订单，快递订单需要调快递100的取消接口
                if (StringUtils.isNotEmpty(recycleOrder.getKuaidinum())) {
                    LogisticsExpenditureStatistics logisticsExpenditureStatistics = logisticsExpenditureStatisticsMapper.selectOne(new LambdaQueryWrapper<LogisticsExpenditureStatistics>().eq(LogisticsExpenditureStatistics::getLogisticsNumber, recycleOrder.getRecycleOrderNo()).eq(LogisticsExpenditureStatistics::getKuaidinum, recycleOrder.getKuaidinum()));
                    if (ObjectUtils.isNotEmpty(logisticsExpenditureStatistics)) {
                        try {
                            cancelDeBangOrder(logisticsExpenditureStatistics);
                        } catch (Exception e) {
                            log.error("跟快递100撤销订单失败，失败原因{}", e.getMessage(), e);
                            return AjaxResult.error("取消快递订单失败，请注意留意快递员电话，告知订单取消寄出");

                        }
                    }
                }
            } else {
                return AjaxResult.error("仅待接单与待上门状态的订单可以取消");
            }
            //判断是否已许愿订单，如果是已许愿订单，还需要同步删除许愿记录
            clientPrayerManagementMapper.delete(new LambdaQueryWrapper<ClientPrayerManagement>().eq(ClientPrayerManagement::getRecycleOrderId,recycleOrder.getRecycleOrderNo()));

        } else {
            HousekeepingOrder housekeepingOrder = housekeepingOrderService.getById(orderNo);
            if (ObjectUtils.isEmpty(housekeepingOrder)) {
                return AjaxResult.error("不存在订单号为：" + orderNo + "，的订单");
            }
            if ("1".equals(housekeepingOrder.getStatus()) || "2".equals(housekeepingOrder.getStatus())) {
                housekeepingOrder.setStatus("6");
                housekeepingOrderService.updateById(housekeepingOrder);
            } else {
                return AjaxResult.error("仅待接单与待上门状态的订单可以取消");
            }
        }
        return AjaxResult.success("取消成功");
    }


    @Override
    public AjaxResult launchHousekeepingOrderPayPrepare(String hkOrderNo) {
        HousekeepingOrder housekeepingOrder = housekeepingOrderService.getById(hkOrderNo);

        if (!"4".equals(housekeepingOrder.getStatus())) {
            return AjaxResult.error("仅待支付订单可发起支付，若已完成服务，请让服务人员在服务平台操作已完成后，再发起支付申请");
        }
        ClientUserManagement clientUserManagement = clientUserManagementMapper.selectById(housekeepingOrder.getClientId());

        if (ObjectUtils.isEmpty(clientUserManagement)) {
            return AjaxResult.error("服务器异常，无法读取当前服务器订单的客户，请联系管理员处理");
        }
        BigDecimal totalMoney = housekeepingOrder.getPracticalMoney();
        LaunchHousekeepingOrderPayPrepareVo launchHousekeepingOrderPayPrepareVo = new LaunchHousekeepingOrderPayPrepareVo();
        launchHousekeepingOrderPayPrepareVo.setClientIntegral(clientUserManagement.getIntegral());
        launchHousekeepingOrderPayPrepareVo.setTotalMoney(totalMoney);

        IntegralConfig integralConfig = integralConfigMapper.selectById(1);
        Long integral = integralConfig.getIntegral();
        BigDecimal totalIntegral = totalMoney.multiply(new BigDecimal(integral));

        if (clientUserManagement.getIntegral() == null || clientUserManagement.getIntegral() < 1) {
            //用户没有积分
            launchHousekeepingOrderPayPrepareVo.setPayMoney(totalMoney);
            launchHousekeepingOrderPayPrepareVo.setDeductionIntegral(0L);
            launchHousekeepingOrderPayPrepareVo.setDeductionMoney(new BigDecimal(0));
        } else {
            //用户有积分
            if (totalIntegral.compareTo(new BigDecimal(clientUserManagement.getIntegral())) < 0) {
                //用户积分足以支付全部金额
                launchHousekeepingOrderPayPrepareVo.setDeductionIntegral(totalIntegral.longValue());
                launchHousekeepingOrderPayPrepareVo.setDeductionMoney(totalMoney);
                launchHousekeepingOrderPayPrepareVo.setPayMoney(new BigDecimal(0));
            } else {
                //用户积分不足以支付全部金额
                DecimalFormat df = new DecimalFormat("0.00");
                BigDecimal integralMoney = new BigDecimal(df.format((float)clientUserManagement.getIntegral()/integral)).setScale(2, RoundingMode.HALF_UP);
                BigDecimal subtract = totalMoney.subtract(integralMoney).setScale(2, RoundingMode.HALF_UP);
                launchHousekeepingOrderPayPrepareVo.setPayMoney(subtract);
                launchHousekeepingOrderPayPrepareVo.setDeductionIntegral(clientUserManagement.getIntegral());
                launchHousekeepingOrderPayPrepareVo.setDeductionMoney(integralMoney);
            }
        }

        return AjaxResult.success(launchHousekeepingOrderPayPrepareVo);
    }


    @Override
    public AjaxResult housekeepingPayment(HousekeepingPayment payment) {

        ClientUserManagement clientUserManagement = clientUserManagementMapper.selectById(payment.getUserId());

        if (payment.getTotalIntegral() > clientUserManagement.getIntegral()) {
            Map<String, String> map = new HashMap<>();
            map.put("code", "500");
            map.put("result", "您当前积分不足以支付当前订单,该订单总需要积分为：" + payment.getTotalIntegral() + "您当前的积分为：" + clientUserManagement.getIntegral());
            return AjaxResult.error("您当前积分不足以支付当前订单,该订单总需要积分为：" + payment.getTotalIntegral() + "您当前的积分为：" + clientUserManagement.getIntegral()).put("resultMap", map);
        }

        Map<String, String> pay = new HashMap<>();
        if (payment.getTotalMoney().compareTo(BigDecimal.ZERO) == 0) {
            //积分足以支付，不需要走微信支付
            pay.put("whether", "N");
        } else {
            //积分加金额支付或者纯金额支付
            //调起微信支付
            String orderId = orderNoGenerateUtil.getIncr(OrderInfoConstant.WITHDRAW_ORDER);
            PaymentDTO paymentDTO = new PaymentDTO();
            paymentDTO.setOrderNo(orderId);
            paymentDTO.setTotalFee(payment.getTotalMoney());
            paymentDTO.setOpenId(clientUserManagement.getOpenid());
            paymentDTO.setProductDetail("商品购买");
            paymentDTO.setAccount(clientUserManagement.getUserName());

            paymentDTO.setAppId(wxproperties.getClientAppId());
            paymentDTO.setNotifyUrl("https://bluestarhuman.com/recycle/clientProgram/shopping/housekeepingPayCallBack");
            pay = wechatPaymentService.pay(paymentDTO);
            pay.put("orderNo",orderId);
            pay.put("whether","Y");
        }

        return AjaxResult.success(pay);
    }

    @Override
    public AjaxResult housekeepingPaymentEnd(HousekeepingPayment payment) {
        ClientUserManagement clientUserManagement = clientUserManagementMapper.selectById(payment.getUserId());
        //减扣用户积分
        clientUserManagement.setIntegral(clientUserManagement.getIntegral() - payment.getTotalIntegral());
        clientUserManagementMapper.updateById(clientUserManagement);
        HousekeepingOrder housekeepingOrder = housekeepingOrderService.getById(payment.getHkOrderNo());
        if (payment.getTotalMoney().compareTo(BigDecimal.ZERO) == 0) {
            //积分足以支付，不需要走微信支付
            //结算积分给综合站
            extracted(payment.getHkOrderNo(),BigDecimal.valueOf(payment.getTotalIntegral()), housekeepingOrder.getMerchantId());
            housekeepingOrder.setIncomeIntegral(payment.getTotalIntegral().intValue());
        } else {
            //积分加金额支付或者纯金额支付
            //调起微信支付
            housekeepingOrder.setPaymentNo(payment.getOrderNo());
            //计算综合站实际总得
            BigDecimal totalMoney = housekeepingOrder.getPracticalMoney();
            IntegralConfig integralConfig = integralConfigMapper.selectById(1);
            Long integral = integralConfig.getIntegral();
            housekeepingOrder.setIncomeIntegral(totalMoney.multiply(new BigDecimal(integral)).intValue());
            extracted(payment.getHkOrderNo(),totalMoney.multiply(new BigDecimal(integral)), housekeepingOrder.getMerchantId());
        }

        //记录用户积分记录
        if (payment.getTotalIntegral() > 0) {
            BillRecord billRecord = new BillRecord();
            billRecord.setOrderNo(payment.getHkOrderNo());
            billRecord.setCreateTime(new Date());
            billRecord.setOutput(BigDecimal.valueOf(payment.getTotalIntegral()));
            billRecord.setUserId(clientUserManagement.getId());
            billRecord.setUserType(1);
            billRecord.setType(5);
            billRecordMapper.insert(billRecord);
        }
        //修改订单状态
        housekeepingOrder.setStatus("5");
        housekeepingOrder.setUpdatedTime(new Date());
        housekeepingOrder.setUpdatedBy("WX");
        housekeepingOrderService.updateById(housekeepingOrder);

        return AjaxResult.success("结算成功");

    }

    @Override
    public AjaxResult checkRecycleOrderPrayerRecord(String orderNo) {
        Boolean result = false;
        Integer integer = clientPrayerManagementMapper.selectCount(new LambdaQueryWrapper<ClientPrayerManagement>().eq(ClientPrayerManagement::getRecycleOrderId, orderNo));
        if (integer > 0){
            result = true;
        }
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult getTotalRecycleOrder() {
        Long daysPassed = 1l;
        try {
            LocalDate pastDate = LocalDate.parse(FAKE_DATA_DATE);
            LocalDate currentDate = LocalDate.now();
            daysPassed = ChronoUnit.DAYS.between(pastDate, currentDate);
        }catch (Exception e){
            log.error("获取过去多少天失败，详情为{}",e.getMessage(),e);
        }
        int count = recycleOrderService.count();
        Long result = (daysPassed *  STEP) + count;
        return AjaxResult.success(result);
    }

    //记录综合站所得
    private void extracted(String orderNo, BigDecimal totalIntegral,Long merchantId) {
        BillRecord billRecord = new BillRecord();
        billRecord.setOrderNo(orderNo);
        billRecord.setCreateTime(new Date());
        billRecord.setIncome(totalIntegral);
        billRecord.setUserId(merchantId);
        billRecord.setUserType(2);
        billRecord.setType(5);
        billRecordMapper.insert(billRecord);

        MerchantManagement merchantManagement = managementMapper.selectById(merchantId);
        merchantManagement.setIntegral(merchantManagement.getIntegral() + totalIntegral.longValue());
        merchantManagement.setUpdatedTime(new Date());
        merchantManagement.setUpdatedBy("JZORDER");
        managementMapper.updateById(merchantManagement);
    }

    @Override
    public Map<String, String> housekeepingPayCallBack(HttpServletRequest request) {
        log.debug("微信支付回调数据：" + String.valueOf(request));
        Map<String, String> returnMap = new HashMap<>();
        try {
            String requestBody = wechatPaymentService.getRequestBody(request);
            log.info("回调接收到的参数为：{}", JSON.toJSONString(requestBody));

            if (wechatPaymentService.verifiedSign(request, requestBody)) {
                //微信支付通知实体类
                log.info("进行微信支付回调信息JSON格式转换,转换的JSON是：{}",requestBody);
                PayCallBackInfo payCallBackInfo = com.alibaba.fastjson.JSONObject.parseObject(requestBody, PayCallBackInfo.class);
                log.info("微信支付通知实体类解析成功，解析数据为：{}",payCallBackInfo.toString());
                //如果支付成功
                if ("TRANSACTION.SUCCESS".equals(payCallBackInfo.getEvent_type())) {
                    //通知资源数据
                    PayCallBackInfo.Resource resource = payCallBackInfo.getResource();
                    //解密后资源数据
                    String notifyResourceStr = AesUtil.decryptToString(wxproperties.getApiV3Key().getBytes(StandardCharsets.UTF_8),
                            resource.getAssociated_data().getBytes(StandardCharsets.UTF_8),
                            resource.getNonce().getBytes(StandardCharsets.UTF_8), resource.getCiphertext());
                    log.info("微信支付解密后资源数据成功，解析数据为：{}",notifyResourceStr);
                    //通知资源数据对象
                    ResourceInfo decryptResource = com.alibaba.fastjson.JSONObject.parseObject(notifyResourceStr, ResourceInfo.class);
                    final String outTradeNo = decryptResource.getOut_trade_no();
                    Integer total = decryptResource.getAmount().getTotal();

                    HousekeepingOrder housekeepingOrder = housekeepingOrderService.getOne(new LambdaQueryWrapper<HousekeepingOrder>().eq(HousekeepingOrder::getPaymentNo, outTradeNo));

                    if (ObjectUtils.isEmpty(housekeepingOrder)){
                        throw new RuntimeException("根据支付编码无法找到对应的家政服务订单，请跟进处理");
                    }

                    IntegralConfig integralConfig = integralConfigMapper.selectById(1);
                    DecimalFormat df = new DecimalFormat("0.00");
                    if (housekeepingOrder.getIncomeIntegral() > 0){
                        if (integralConfig.getIntegral() == 100) {
                            total = total + housekeepingOrder.getIncomeIntegral();
                        }else {
                            BigDecimal moeny = new BigDecimal((df.format((float)housekeepingOrder.getIncomeIntegral()/integralConfig.getIntegral()))).multiply(new BigDecimal(100));
                            total = total + moeny.intValue();
                        }
                    }

                    BigDecimal amountPay = (new BigDecimal(total).divide(new BigDecimal("100"))).setScale(2);
                    if (amountPay.compareTo(housekeepingOrder.getPracticalMoney()) != 0) {
                        returnMap.put("code", "500");
                        returnMap.put("message", "微信支付金额与蓝星人订单记录金额不一致");
                        //记录日志
                        recycleRequestLogService.save(new RecycleRequestLog().
                                setRequestData(decryptResource.toString()).
                                setResponseData(returnMap.toString()).
                                setRemark("警告：微信支付回调信息异常信息请注意处理").
                                setLogType("微信支付").
                                setCreateBy("ADMIN").
                                setCreateDate(new Date()).
                                setRequestUser("微信").
                                setResponseUser("蓝星人"));
                        return returnMap;
                    }
                    housekeepingOrder.setStatus("5");
                    housekeepingOrderService.updateById(housekeepingOrder);
                    BigDecimal multiply = housekeepingOrder.getPracticalMoney().multiply(new BigDecimal(integralConfig.getIntegral()));
                    BillRecord billRecord = new BillRecord();
                    billRecord.setOrderNo(housekeepingOrder.getHKOrderNo());
                    billRecord.setCreateTime(new Date());
                    billRecord.setIncome(multiply);
                    billRecord.setUserId(housekeepingOrder.getMerchantId());
                    billRecord.setUserType(2);
                    billRecord.setType(5);
                    billRecordMapper.insert(billRecord);

                    returnMap.put("code", "SUCCESS");
                }
            }
        } catch (Exception e) {
            //记录日志
            recycleRequestLogService.save(new RecycleRequestLog().
                    setRequestData(request.toString()).
                    setResponseData(e.getMessage()).
                    setRemark("警告：微信支付家政服务回调信息异常信息请注意处理").
                    setLogType("微信支付").
                    setCreateBy("ADMIN").
                    setCreateDate(new Date()).
                    setRequestUser("微信").
                    setResponseUser("蓝星人"));

            log.error("支付失败原因:{}",e.getMessage(),e);
            returnMap.put("code", "500");
            returnMap.put("message", "系统错误");
            return returnMap;
        }

        recycleRequestLogService.save(new RecycleRequestLog().
                setRequestData(request.toString()).
                setResponseData(returnMap.toString()).
                setRemark("微信支付家政服务回调信息").
                setLogType("微信支付").
                setCreateBy("ADMIN").
                setCreateDate(new Date()).
                setRequestUser("微信").
                setResponseUser("蓝星人"));
        return returnMap;
    }


    public void cancelDeBangOrder(LogisticsExpenditureStatistics logisticsExpenditureStatistics) throws Exception {

        CancelDeBangOrderRequest printReq = new CancelDeBangOrderRequest();
        printReq.setCancelTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        printReq.setLogisticID(logisticsExpenditureStatistics.getTaskId());
        printReq.setMailNo(logisticsExpenditureStatistics.getKuaidinum());
        printReq.setLogisticCompanyID("DEPPON");
        printReq.setRemark("用户取消订单");

        Long timestamp = System.currentTimeMillis();
        String params = FastJsonUtil.toJSONString(printReq);
        System.out.println("params = " + params);
        String digest = getDigest(params + APP_KEY + timestamp);
        NameValuePair[] data = new NameValuePair[4];
        data[0] = new NameValuePair("companyCode", COMPANY_CODE);
        data[1] = new NameValuePair("digest", digest);
        data[2] = new NameValuePair("timestamp", timestamp.toString());
        data[3] = new NameValuePair("params", params);
        //返回结果
        ResultDO<String> response= HttpUtils.sendRequest(DEPPON_URL, data, "UTF-8", 5000);
        Gson gson = new Gson();
        CancelDeBangOrderResponse result = gson.fromJson(response.getModel(), CancelDeBangOrderResponse.class);
        recycleRequestLogService.save(new RecycleRequestLog().
                setRequestData(String.valueOf(printReq)).
                setResponseData(result.toString()).
                setRemark("取消寄件").
                setLogType("取消寄件").
                setCreateBy("ADMIN").
                setCreateDate(new Date()).
                setRequestUser("蓝星人").
                setResponseUser("德邦快递"));
    }

    private static String getDigest(String plainText) {
        return Base64.encodeBase64String(DigestUtils.md5Hex(plainText).getBytes());
    }


    private void putIntoPocket(Pocket requestPocket) {
        final String pocketKey = POCKET_PREFIX + requestPocket.getUserId();
        ValueOperations<String, List<Pocket>> opsForValue = pocketCache.opsForValue();
        List<Pocket> existPocketProducts = opsForValue.get(pocketKey);

        if (CollUtil.isNotEmpty(existPocketProducts)) {
            //重组redis对象数据
            JSONArray jsonArray = new JSONArray(existPocketProducts);

            existPocketProducts = new ArrayList<>();

            for (int i = 0; i < jsonArray.length(); i++) {
                Pocket pocket = new Pocket();
                JSONObject object = jsonArray.getJSONObject(i);
                String integralCommodityStr = object.get("integralCommodity").toString();
                IntegralCommodity integralCommodity = JSON.parseObject(integralCommodityStr, IntegralCommodity.class);

                String integralCommoditySizeStr = object.get("integralCommoditySize").toString();
                IntegralCommoditySize integralCommoditySize = JSON.parseObject(integralCommoditySizeStr, IntegralCommoditySize.class);

                pocket.setCreateDate(object.get("createDate").toString());
                pocket.setQuantity((int) object.get("quantity"));
                Integer userId = (int) object.get("userId");
                pocket.setUserId(userId.longValue());
                pocket.setIntegralCommodity(integralCommodity);
                pocket.setIntegralCommoditySize(integralCommoditySize);
                existPocketProducts.add(pocket);
            }
        }

        if (CollUtil.isNotEmpty(existPocketProducts)) {

            final boolean match = existPocketProducts.stream().anyMatch(existPocket -> {
                if (existPocket.getIntegralCommodity() != null && existPocket.getIntegralCommoditySize() != null) {
                    Long commodityId = existPocket.getIntegralCommodity().getId();
                    Long sizeId = existPocket.getIntegralCommoditySize().getId();
                    if (requestPocket.getIntegralCommodity().getId() == commodityId && requestPocket.getIntegralCommoditySize().getId() == sizeId) {
                        return true;
                    }
                }
                return false;
            });
            if (match) {
                for (Pocket existPocketProduct : existPocketProducts) {
                    if (existPocketProduct.getIntegralCommodity().getId() == requestPocket.getIntegralCommodity().getId() && existPocketProduct.getIntegralCommoditySize().getId() == requestPocket.getIntegralCommoditySize().getId()) {
                        existPocketProduct.setQuantity(existPocketProduct.getQuantity() + requestPocket.getQuantity());
                    }
                }
                opsForValue.set(pocketKey, existPocketProducts, 30 * 3, TimeUnit.DAYS);
            } else {
                existPocketProducts.add(requestPocket);
                opsForValue.set(pocketKey, CollUtil.newArrayList(existPocketProducts), 30 * 3, TimeUnit.DAYS);
            }
        } else {
            opsForValue.set(pocketKey, CollUtil.newArrayList(requestPocket), 30 * 3, TimeUnit.DAYS);
        }
    }

    @Override
    public List<ClientPrayerManagement> prayerList() {
        List<ClientPrayerManagement> clientPrayerManagements = clientPrayerManagementMapper.selectList(new LambdaQueryWrapper<>());
        clientPrayerManagements.forEach(c->c.setUserName(maskUsername(c.getUserName())));
        return clientPrayerManagements;
    }

    public static String maskUsername(String username) {
        int length = username.length();
        if (length < 2) {
            return username;
        }
        if (length == 2){
            return username.charAt(0) + "*";
        }

        StringBuilder maskedText = new StringBuilder();
        for (int i = 1; i < length - 1; i++) {
            maskedText.append("*");
        }

        return username.charAt(0) + maskedText.toString() + username.charAt(length - 1);
    }
}
